package com.gthncz;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;

public class Duoduodemo2 {

    private static class Coor {
        int i, j;
        public Coor(int x, int y) {i = x; j=y;}
    }

    private static void bfsDistance(int[][] matrix, int[][] conj, boolean[][] visited, int i, int j, int n, int m, int[][] distance) {
        if (i < 0 || j < 0 || i == n || j == m) return;
        Deque<Coor> queue = new ArrayDeque<>();
        queue.offer(new Coor(i, j));
        int level = 0;
        while (!queue.isEmpty()) {
            Coor coor = queue.poll();
            visited[i][j] = true;
            if (conj[i][j] != conj[coor.i][coor.j]) {
                int now = distance[conj[i][j]-1][conj[coor.i][coor.j]-1];
                distance[conj[i][j]-1][conj[coor.i][coor.j]-1] = Math.min(now, level);
            }

            ++level;
            // 上
            if (coor.i -1 >= 0 && !visited[coor.i -1][coor.j]) {
                queue.offer(new Coor(coor.i-1, coor.j));
            }
            if (coor.j-1 >= 0 && !visited[coor.i][coor.j-1]) {
                queue.offer(new Coor(coor.i, coor.j-1));
            }
            if (coor.i+1 < n && !visited[coor.i+1][coor.j]) {
                queue.offer(new Coor(coor.i+1, coor.j));
            }
            if (coor.j+1 < n && !visited[coor.i][coor.j+1]) {
                queue.offer(new Coor(coor.i, coor.j+1));
            }
        }
    }


    private static void dfsLabel(int[][] matrix, int[][] conj, boolean[][] visited, int i, int j, int n, int m, int count, int[] graphLength) {
        if (i == n || m == j) return;
        if (matrix[i][j] == 1) {
            conj[i][j] = count;
            visited[i][j] = true;
            ++graphLength[count-1];
            // 上
            if (i-1 >= 0 && visited[i-1][j] == false) dfsLabel(matrix, conj, visited, i-1, j, n, m, count, graphLength);
            // 左
            if (j-1 >= 0 && visited[i][j-1] == false) dfsLabel(matrix, conj, visited, i, j-1, n, m, count, graphLength);
            // 下
            if (i+1 < n && visited[i+1][j] == false) dfsLabel(matrix, conj, visited, i+1, j, n, m, count, graphLength);
            // 右
            if (j+1 < n && visited[i][j+1] == false) dfsLabel(matrix, conj, visited, i, j+1, n, m, count, graphLength);
        } else {
            conj[i][j] = 0;
            visited[i][j] = true;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();

        if (n < 1 || m < 1) {
            System.out.printf("0");
            return;
        }

        int[][] matrix = new int[n][m];
        for (int i=0; i<n ; ++i) {
            for (int j=0; j<m; ++j) {
                matrix[i][j] = sc.nextInt();
            }
        }


        int[][] conj = new int[n][m];
        boolean[][] visited = new boolean[n][m];

        // 连通分量标记
        int count = 1;
        int[] graghLength = new int[Math.max(n, m)];
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                if (!visited[i][j]) {
                    dfsLabel(matrix, conj, visited, i, j, n, m, count, graghLength);
                    ++count;
                }
            }
        }

        // 还原 visited
        for (int i=0; i<n; ++i) {
            for (int j = 0; j < m; ++j) {
                visited[i][j] = false;
            }
        }

        // bfs 查找任意两个连通图之间最短距离
        int num_graphs = count - 1;
        int[][] distance = new int[num_graphs][num_graphs];
        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                distance[i][j] = Integer.MAX_VALUE;
            }
        }

        for (int i=0; i<n; ++i) {
            for (int j=0; j<m; ++j) {
                if (!visited[i][j] && matrix[i][j] == 1) {
                    bfsDistance(matrix, conj, visited, i, j, n, m, distance);
                }
            }
        }

        // 找出距离为1, 连通分量之和最大
        int max = Integer.MIN_VALUE;
        for (int i=0; i<num_graphs; ++i) {
            for (int j=i+1; j<num_graphs; ++j) {
                if (distance[i][j] == 1) {
                    max = Math.max(max, graghLength[i] + graghLength[j]+1);
                }
            }
        }

        System.out.printf("%d", max);
    }

}
